
import dynamicScrollViewV2 from "./dynamicScrollViewV2";
import { _decorator } from 'cc';
const { ccclass, property } = _decorator;

@ccclass
export default class dynamicScrollViewDataV2 extends dynamicScrollViewV2 {

    rankingsDic: any = null;

    @property
    fetchBatchCount: number = 20;

    keyNow: string = 'default';

    @property
    clearCacheWhenChangeKey: boolean = false;

    init() {
        super.init();
        this.rankingsDic = {};
        this.minRefreshRank = this.compatibleMaxCount;
        this.maxRefreshRank = 0;
    }

    dataSourceChanged(key: string, initRank: number) {
        if (this.ready) {
            this.reset(key, true);
            if (initRank != null) {
                this.gotoRank(initRank);
            }
        }
        else this.open(key, 0);
    }

    open(firstKey: string, initRank: number) {
        if (!this.ready) this.init();
        this.setKeyNow(firstKey, null);
        this.prepare();
        this.gotoRank(initRank);
    }

    close() {
        this.clearPool();
    }

    reset(key, clearData = false) {
        this.scrollView.stopAutoScroll();
        if (this.clearCacheWhenChangeKey) { delete this.rankingsDic[this.keyNow]; }

        if (key != null) {
            this.keyNow = key;
        }

        this.minRefreshRank = this.compatibleMaxCount;
        this.maxRefreshRank = 0;

        if (clearData) this.rankingsDic = {};
        this.clearContent();
    }

    setKeyNow(key, initRank: any) {
        if (this.keyNow != key) {
            this.keyNow = key;

            if (this.clearCacheWhenChangeKey) { delete this.rankingsDic[key]; }

            this.scrollView.stopAutoScroll();

            this.minRefreshRank = this.compatibleMaxCount;
            this.maxRefreshRank = 0;

            this.clearContent();

            if (initRank != null) this.gotoRank(initRank);
        }
    }

    getKeyNow() {
        return this.keyNow;
    }

    fetchDataForKey(key: string, skip: number, count: number, addDataFunc: Function) { }

    setKeyValueToRow(dataRow, key, value) {
        dataRow[key] = value;
    }

    getKeyValueToRow(dataRow, key) {
        return dataRow[key];
    }

    getRankFromDataRow(dataRow) {
        return dataRow.rank;
    }

    setRankToDataRow(dataRow, rank) {
        dataRow.rank = rank;
    }

    createEmptyRow(rank, status) {
        let row: any = {};
        this.setRankToDataRow(row, rank);
        if (status != null) this.setKeyValueToRow(row, '_status', status);
        return row;
    }

    initForKey(key) {
        if (this.rankingsDic == null) this.rankingsDic = {};
        if (this.rankingsDic[key] == null) this.rankingsDic[key] = { rankings: null, fetchingFlag: {} };
    }

    fetchRanking(skip, groupKey) {
        this.log('fetchRanking', groupKey, skip, '~', skip + this.fetchBatchCount - 1);
        let key = groupKey;

        this.initForKey(key);

        this.fetchDataForKey(key, skip, this.fetchBatchCount, function (rankings) {
            this.addData(rankings, skip, key);
        }.bind(this));
    }

    // 需要填充数据层为 rank为key的形式
    addData(rankings: Array<any>, skip: number, groupKey: string) {
        let key = groupKey;

        if (this.rankingsDic[key] == null) this.rankingsDic[key] = {};
        if (this.rankingsDic[key].rankings == null) this.rankingsDic[key].rankings = {};

        let needLastRank = skip + this.fetchBatchCount - 1;

        let realFirstRank = this.compatibleMaxCount;
        let realLastRank = -1;



        for (let i = 0; i < rankings.length; i++) {
            let ranking = rankings[i];
            if (realFirstRank > ranking.rank) realFirstRank = ranking.rank;
            if (realLastRank < ranking.rank) realLastRank = ranking.rank;
            this.setKeyValueToRow(ranking, '_status', 1);
            this.rankingsDic[key].rankings[ranking.rank] = ranking;

            this.refreshSingle(ranking.rank, key); // 主动刷新单独行

            if (ranking._isLast) {
                realLastRank = ranking.rank;
                this.setMaxRank(realLastRank);
            }
        }

        this.log('realLastRank/needLastRank', realLastRank, needLastRank);
        if (realLastRank < needLastRank && realLastRank >= 0) { //  没有更往后的了
            this.setMaxRank(realLastRank);
            for (let i = realLastRank + 1; i <= needLastRank; i++) {
                this.refreshSingle(i, key);
            }
        } else if (skip >= 0 && rankings.length == 0) { // 判定没有更多数据了（例如每次取20个数据，而恰好总共只有40个数据，那么再取40~59的数据时会返回空列表，此时就可以判定maxRank为skip-1）
            this.setMaxRank(skip - 1);
        }
    }

    getRowDataAtRank(rank, groupKey) {
        if (this.rankingsDic) {
            let key = groupKey;
            if (this.rankingsDic[key]) {
                // cc.log('getRowDataAtRank', rank, groupKey, this.rankingsDic[key]);
                if (this.rankingsDic[key].rankings) {
                    if (rank > this.maxRank) return this.createEmptyRow(rank, 2);
                    if (this.rankingsDic[key].rankings) {
                        let rowData = this.rankingsDic[key].rankings[rank];
                        if (rowData) {
                            return rowData;
                        }
                    }
                }
            }
        }
        return this.createEmptyRow(rank, 0);
    }

    requireFetch(rank, groupKey) {
        // 如果没有在查询才开始
        let key = groupKey;
        this.initForKey(key);
        let fetchSkip = this.getRankFetchFirst(rank);
        if (this.rankingsDic[key].fetchingFlag[fetchSkip] && this.rankingsDic[key].fetchingFlag[fetchSkip] == 1) { // 已经fetch过了
        } else {
            this.rankingsDic[key].fetchingFlag[fetchSkip] = 1;
            this.fetchRanking(fetchSkip, groupKey);
        }
    }

    getRankFetchFirst(rank) {
        return Math.floor(rank / this.fetchBatchCount) * this.fetchBatchCount;
    }

}
